home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / util / arc / xadmaster.lha / xad / Developer / Sources / tools / xadUnDisk.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-31  |  13.1 KB  |  472 lines

  1. #define NAME         "xadUnDisk"
  2. #define DISTRIBUTION "(Freeware) "
  3. #define REVISION     "10"
  4. #define DATE         "21.08.2000"
  5.  
  6. /* Programmheader
  7.  
  8.     Name:        xadUnDisk
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    dearchives disk archives
  12.     Compileropts:    -
  13.     Linkeropts:    -gsi -l amiga
  14.  
  15.  1.0   18.11.98 : first version
  16.  1.1   23.12.98 : added support for FILEDESCRIPT
  17.  1.2   04.02.99 : added file corrupt message, new InfoText system and SAVETEXTS
  18.  1.3   16.02.99 : bug fix in report hook
  19.  1.4   28.02.99 : little bug fix in chunk hook
  20.  1.5   15.09.99 : added insert disk question
  21.  1.6   20.02.00 : added FORMAT keyword and ADF to disk
  22.  1.7   19.03.00 : bug fix
  23.  1.8   12.04.00 : image question only, if XADERR_FILETYPE
  24.  1.9   07.07.00 : added NOASKINSERT keyword
  25.  1.10  21.08.00 : now uses xadGetHookAccess instead of own image copy
  26. */
  27.  
  28. #include <proto/xadmaster.h>
  29. #include <proto/exec.h>
  30. #include <proto/dos.h>
  31. #include <proto/utility.h>
  32. #include <exec/memory.h>
  33. #include <devices/trackdisk.h>
  34. #include <dos/dosasl.h>
  35. #include <dos/filehandler.h>
  36. #include <utility/hooks.h>
  37. #include "SDI_version.h"
  38. #include "SDI_compiler.h"
  39. #define SDI_TO_ANSI
  40. #include "SDI_ASM_STD_protos.h"
  41.  
  42. struct xadMasterBase *   xadMasterBase = 0;
  43. struct DosLibrary *     DOSBase = 0;
  44. struct ExecBase *     SysBase  = 0;
  45.  
  46. #define PARAM    "FROM/A,TO,LOWCYL/N,HIGHCYL/N,ENTRY/N,PASSWORD,SAVETEXTS/K," \
  47.         "NE=NOEXTERN/S,INFO=LIST/S,SHOWTEXTS/S,OW=OVERWRITE/S,"    \
  48.         "IG=IGNOREGEOMETRY/S,FORMAT/S,DIMG=DISKIMAGE/S,NAI=NOASKINSERT/S"
  49.  
  50. struct Args {
  51.   STRPTR from;
  52.   STRPTR to;
  53.   LONG * lowcyl;
  54.   LONG * highcyl;
  55.   LONG * entry;
  56.   STRPTR password;
  57.   STRPTR savetexts;
  58.   ULONG  noextern;
  59.   ULONG  info;
  60.   ULONG  showtexts;
  61.   ULONG  overwrite;
  62.   ULONG  ignoregeometry;
  63.   ULONG  format;
  64.   ULONG  diskimage;
  65.   ULONG  noaskinsert;
  66. };
  67.  
  68. ASM(ULONG) SAVEDS progrhook(REG(a0, struct Hook *),
  69.   REG(a1, struct xadProgressInfo *));
  70. struct Hook prhook = {{0,0},(ULONG (*)()) progrhook, 0, 0};
  71. void ShowTexts(struct xadTextInfo *ti);
  72. void SaveTexts(struct xadTextInfo *ti, STRPTR name);
  73. LONG WriteDisk(struct Args *);
  74. LONG AskInsertDisk(STRPTR);
  75.  
  76. ULONG start(void)
  77. {
  78.   ULONG ret = RETURN_FAIL;
  79.   struct DosLibrary *dosbase;
  80.  
  81.   SysBase = (*((struct ExecBase **) 4));
  82.   { /* test for WB and reply startup-message */
  83.     struct Process *task;
  84.     if(!(task = (struct Process *) FindTask(0))->pr_CLI)
  85.     {
  86.       WaitPort(&task->pr_MsgPort);
  87.       Forbid();
  88.       ReplyMsg(GetMsg(&task->pr_MsgPort));
  89.       return RETURN_FAIL;
  90.     }
  91.   }
  92.  
  93.   if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  94.   {
  95.     LONG err = 0;
  96.     struct xadMasterBase *xadmasterbase;
  97.  
  98.     DOSBase = dosbase;
  99.     if((xadmasterbase = (struct xadMasterBase *)
  100.     OpenLibrary("xadmaster.library", 8)))
  101.     {
  102.       LONG def = 1;
  103.       struct Args args;
  104.       struct RDArgs *rda;
  105.       
  106.       memset(&args, 0 , sizeof(struct Args));
  107.       args.entry = &def;
  108.  
  109.       xadMasterBase = xadmasterbase;
  110.       if((rda = ReadArgs(PARAM, (LONG *) &args, 0)))
  111.       {
  112.     if(args.to || args.info)
  113.     {
  114.       struct xadArchiveInfo *ai;
  115.     
  116.       if(args.diskimage)
  117.       {
  118.         ret = 0;
  119.             err = WriteDisk(&args);
  120.       }
  121.       else if((ai = (struct xadArchiveInfo *)
  122.       xadAllocObjectA(XADOBJ_ARCHIVEINFO, 0)))
  123.       {
  124.         if(!(err = xadGetInfo(ai, XAD_INFILENAME, args.from,
  125.         XAD_NOEXTERN, args.noextern, args.password ? XAD_PASSWORD :
  126.         TAG_IGNORE, args.password, TAG_DONE)))
  127.         {
  128.           if(ai->xai_Flags & XADAIF_FILECORRUPT)
  129.             Printf("!!! The archive file has some corrupt data. !!!\n");
  130.           if(args.info)
  131.           {
  132.             struct xadDiskInfo *xdi;
  133.             Printf("ArchiverName:   %s\n", ai->xai_Client->xc_ArchiverName);
  134.  
  135.             xdi = ai->xai_DiskInfo;
  136.             while(xdi)
  137.             {
  138.           if(xdi->xdi_EntryNumber != 1 || xdi->xdi_Next)
  139.                 Printf("\nEntry:          %ld\n", xdi->xdi_EntryNumber);
  140.               Printf("EntryInfo:      %s\n", xdi->xdi_EntryInfo ? xdi->xdi_EntryInfo : "<none>");
  141.               Printf("SectorSize:     %ld\n", xdi->xdi_SectorSize);
  142.               Printf("Sectors:        %ld\n", xdi->xdi_TotalSectors);
  143.               Printf("Cylinders:      %ld\n", xdi->xdi_Cylinders);
  144.               Printf("CylSectors:     %ld\n", xdi->xdi_CylSectors);
  145.               Printf("Heads:          %ld\n", xdi->xdi_Heads);
  146.               Printf("TrackSectors:   %ld\n", xdi->xdi_TrackSectors);
  147.               Printf("LowCyl:         %ld\n", xdi->xdi_LowCyl);
  148.               Printf("HighCyl:        %ld\n", xdi->xdi_HighCyl);
  149.               if(xdi->xdi_Flags & XADDIF_CRYPTED)
  150.                 Printf("The entry is encrypted\n");
  151.               if(xdi->xdi_TextInfo)
  152.               {
  153.                 STRPTR a;
  154.                 struct xadTextInfo *ti;
  155.  
  156.                 for(ti = xdi->xdi_TextInfo; ti; ti = ti->xti_Next)
  157.                 {
  158.               a = "TextInfo";
  159.               if(ti->xti_Flags & XADTIF_BANNER)
  160.                 a = "Banner";
  161.               else if(ti->xti_Flags & XADTIF_FILEDIZ)
  162.                 a = "DIZ-Text";
  163.  
  164.               if(ti->xti_Size && ti->xti_Text)
  165.                     Printf("There is a %s with size %ld.\n", a, ti->xti_Size);
  166.                   else if(ti->xti_Flags & XADTIF_CRYPTED)
  167.                     Printf("There is a crypted %s.\n", a);
  168.                   else
  169.                     Printf("There is an empty %s.\n", a);
  170.                 }
  171.                 if(args.showtexts)
  172.                   ShowTexts(xdi->xdi_TextInfo);
  173.                 if(args.savetexts)
  174.                   SaveTexts(xdi->xdi_TextInfo, args.savetexts);
  175.               }
  176.               xdi = xdi->xdi_Next;
  177.             }
  178.             ret = 0;
  179.           }
  180.           else
  181.           {
  182.         struct xadDeviceInfo *dvi = 0;
  183.  
  184.             if(args.to[strlen(args.to)-1] == ':' && stricmp(args.to, "NIL:"))
  185.             {
  186.               if((dvi = (struct xadDeviceInfo *)
  187.               xadAllocObjectA(XADOBJ_DEVICEINFO, 0)))
  188.               {
  189.                 args.to[strlen(args.to)-1] = 0; /* strip ':' */
  190.                 dvi->xdi_DOSName = args.to;
  191.               }
  192.               else
  193.                 err = XADERR_NOMEMORY;
  194.             }
  195.             if(args.showtexts || args.savetexts)
  196.             {
  197.               struct xadDiskInfo *xdi = ai->xai_DiskInfo;
  198.  
  199.               while(xdi && xdi->xdi_EntryNumber < *args.entry)
  200.                 xdi = xdi->xdi_Next;
  201.               if(xdi && xdi->xdi_TextInfo)
  202.               {
  203.                 if(args.showtexts)
  204.                   ShowTexts(xdi->xdi_TextInfo);
  205.                 if(args.savetexts)
  206.                   SaveTexts(xdi->xdi_TextInfo, args.savetexts);
  207.               }
  208.             }
  209.         if(dvi && !args.noaskinsert)
  210.           err = AskInsertDisk(args.to);
  211.  
  212.             if(!err && !(err = xadDiskUnArc(ai, dvi ? XAD_OUTDEVICE :
  213.             XAD_OUTFILENAME, dvi ? (ULONG) dvi : (ULONG) args.to,
  214.             XAD_ENTRYNUMBER, *args.entry, args.lowcyl ?
  215.             XAD_LOWCYLINDER : TAG_IGNORE, args.lowcyl ? *args.lowcyl :
  216.             0, args.highcyl ? XAD_HIGHCYLINDER : TAG_IGNORE,
  217.             args.highcyl ? *args.highcyl : 0, XAD_OVERWRITE,
  218.             args.overwrite, XAD_IGNOREGEOMETRY, args.ignoregeometry,
  219.             XAD_FORMAT, args.format, XAD_VERIFY, TRUE, XAD_PROGRESSHOOK,
  220.             &prhook, TAG_DONE)))
  221.               ret = 0;
  222.             if(dvi)
  223.               xadFreeObjectA(dvi, 0);
  224.           }
  225.           xadFreeInfo(ai);
  226.         } /* xadGetInfo */
  227.         else if(err == XADERR_FILETYPE)
  228.         {
  229.           UBYTE r;
  230.  
  231.           ret = 0;
  232.               Printf("Unknown type. Press <I> to write it to disks as image: ");
  233.               Flush(Output());
  234.               SetMode(Input(), TRUE);
  235.               r = FGetC(Input());
  236.               SetMode(Input(), FALSE);
  237.               if(r == 'i' || r == 'I')
  238.             err = WriteDisk(&args);
  239.           else
  240.                 Printf("\n");
  241.         }
  242.  
  243.         xadFreeObjectA(ai, 0);
  244.           } /* xadAllocObject */
  245.         }
  246.         else
  247.           SetIoErr(ERROR_REQUIRED_ARG_MISSING);
  248.  
  249.         FreeArgs(rda);
  250.       } /* ReadArgs */
  251.  
  252.       if(SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
  253.         SetIoErr(ERROR_BREAK);
  254.  
  255.       if(err)
  256.     Printf("An error occured: %s\n", xadGetErrorText(err));
  257.       else if(ret)
  258.         PrintFault(IoErr(), 0);
  259.  
  260.       CloseLibrary((struct Library *) xadmasterbase);
  261.     } /* OpenLibrary xadmaster */
  262.     else
  263.       Printf("Could not open xadmaster.library\n");
  264.     CloseLibrary((struct Library *) dosbase);
  265.   } /* OpenLibrary dos */
  266.   return ret;
  267. }
  268.  
  269. ASM(ULONG) SAVEDS progrhook(REG(a0, struct Hook *hook),
  270. REG(a1, struct xadProgressInfo *pi))
  271. {
  272.   ULONG ret = 0;
  273.  
  274.   switch(pi->xpi_Mode)
  275.   {
  276.   case XADPMODE_ASK:
  277.     {
  278.       UBYTE r;
  279.       if(pi->xpi_Status & XADPIF_OVERWRITE)
  280.       {
  281.         Printf("File already exists, overwrite? (Y|S|\033[1mN\033[0m): ");
  282.         Flush(Output());
  283.         SetMode(Input(), TRUE);
  284.         r = FGetC(Input());
  285.         if(r == 'Y' || r == 'y')
  286.           ret |= XADPIF_OVERWRITE;
  287.         else if(r == 'S' || r == 's')
  288.           ret |= XADPIF_SKIP;
  289.         SetMode(Input(), FALSE);
  290.       }
  291.       if(pi->xpi_Status & XADPIF_IGNOREGEOMETRY)
  292.       {
  293.         Printf("\r\033[KDrive geometry not correct, ignore? (Y|S|\033[1mN\033[0m): ");
  294.         Flush(Output());
  295.         SetMode(Input(), TRUE);
  296.         r = FGetC(Input());
  297.         if(r == 'Y' || r == 'y')
  298.           ret |= XADPIF_IGNOREGEOMETRY;
  299.         else if(r == 'S' || r == 's')
  300.           ret |= XADPIF_SKIP;
  301.         SetMode(Input(), FALSE);
  302.       }
  303.     }
  304.     break;
  305.   case XADPMODE_PROGRESS:
  306.     {
  307.       if(!pi->xpi_DiskInfo)
  308.         Printf("\r\033[KWrote %ld bytes", pi->xpi_CurrentSize);
  309.       else if(pi->xpi_DiskInfo->xdi_Flags & (XADDIF_NOCYLINDERS|XADDIF_NOCYLSECTORS))
  310.       {
  311.         Printf("\r\033[KWrote %ld of %ld bytes (%ld/%ld sectors)",
  312.         pi->xpi_CurrentSize, pi->xpi_DiskInfo->xdi_TotalSectors*
  313.         pi->xpi_DiskInfo->xdi_SectorSize, pi->xpi_CurrentSize/
  314.         pi->xpi_DiskInfo->xdi_SectorSize, pi->xpi_DiskInfo->xdi_TotalSectors);
  315.       }
  316.       else
  317.       {
  318.         ULONG numcyl, fullsize, curcyl, i;
  319.  
  320.         i = pi->xpi_DiskInfo->xdi_CylSectors *
  321.             pi->xpi_DiskInfo->xdi_SectorSize;
  322.         numcyl = pi->xpi_HighCyl+1-pi->xpi_LowCyl;
  323.         fullsize = numcyl * i;
  324.         curcyl = pi->xpi_CurrentSize/i;
  325.  
  326.         Printf("\r\033[KWrote %ld of %ld bytes (%ld/%ld cylinders)",
  327.         pi->xpi_CurrentSize, fullsize, curcyl, numcyl);
  328.       }
  329.       Flush(Output());
  330.     }
  331.     break;
  332.   case XADPMODE_END: 
  333.     if(pi->xpi_DiskInfo->xdi_Flags & (XADDIF_NOCYLINDERS|XADDIF_NOCYLSECTORS))
  334.       Printf("\r\033[KWrote %ld bytes (%ld sectors)\n",
  335.       pi->xpi_CurrentSize, pi->xpi_DiskInfo->xdi_TotalSectors);
  336.     else
  337.       Printf("\r\033[KWrote %ld bytes (%ld cylinders)\n",
  338.       pi->xpi_CurrentSize, pi->xpi_HighCyl+1-pi->xpi_LowCyl);
  339.     break;
  340.   case XADPMODE_ERROR: Printf("\r\033[K");
  341.     break;
  342.   }
  343.  
  344.   if(!(SetSignal(0L,0L) & SIGBREAKF_CTRL_C)) /* clear ok flag */
  345.     ret |= XADPIF_OK;
  346.  
  347.   return ret;
  348. }
  349.  
  350. void ShowTexts(struct xadTextInfo *ti)
  351. {
  352.   ULONG i = 1, j;
  353.   BPTR fh;
  354.   STRPTR a;
  355.  
  356.   fh = Output();
  357.  
  358.   while(!(SetSignal(0L,0L) & SIGBREAKF_CTRL_C) && ti)
  359.   {
  360.     if(ti->xti_Size && ti->xti_Text)
  361.     {
  362.       Printf("»»»» TEXTINFO %ld ««««\n", i);
  363.       a = ti->xti_Text;
  364.       for(j = 0; !(SetSignal(0L,0L) & SIGBREAKF_CTRL_C) && j < ti->xti_Size; ++j)
  365.       {
  366.         if(isprint(*a) || *a == '\n' || *a == '\t' || *a == '\033')
  367.           FPutC(fh, *a);
  368.         else
  369.           FPutC(fh, '.');
  370.         ++a;
  371.       }
  372.       if(*(--a) != '\n')
  373.         FPutC(fh, '\n');
  374.     }
  375.     ti = ti->xti_Next;
  376.     ++i;
  377.   }
  378. }
  379.  
  380. void SaveTexts(struct xadTextInfo *ti, STRPTR name)
  381. {
  382.   UBYTE namebuf[256];
  383.   ULONG i = 1;
  384.   BPTR fh;
  385.   LONG err = 0;
  386.  
  387.   while(!(SetSignal(0L,0L) & SIGBREAKF_CTRL_C) && ti && !err)
  388.   {
  389.     if(ti->xti_Size && ti->xti_Text)
  390.     {
  391.       sprintf(namebuf, "%s.%ld", name, i);
  392.       if((fh = Open(namebuf, MODE_NEWFILE)))
  393.       {
  394.         if(Write(fh, ti->xti_Text, ti->xti_Size) != ti->xti_Size)
  395.           ++err;
  396.         Close(fh);
  397.       }
  398.       else
  399.         ++err;
  400.     }
  401.     ti = ti->xti_Next;
  402.     ++i;
  403.   }
  404.   if(err)
  405.     Printf("Failed to save information texts.\n");
  406. }
  407.  
  408. LONG WriteDisk(struct Args *args)
  409. {
  410.   LONG err = 0;
  411.   struct xadArchiveInfo *ai;
  412.   struct xadDeviceInfo *dvi = 0;
  413.  
  414.   if((ai = (struct xadArchiveInfo *) xadAllocObjectA(XADOBJ_ARCHIVEINFO, 0)))
  415.   {
  416.     if(args->to[strlen(args->to)-1] == ':' && stricmp(args->to, "NIL:"))
  417.     {
  418.       if((dvi = (struct xadDeviceInfo *) xadAllocObjectA(XADOBJ_DEVICEINFO, 0)))
  419.       {
  420.         args->to[strlen(args->to)-1] = 0; /* strip ':' */
  421.         dvi->xdi_DOSName = args->to;
  422.       }
  423.       else
  424.         err = XADERR_NOMEMORY;
  425.     }
  426.  
  427.     if(dvi && !args->noaskinsert)
  428.       err = AskInsertDisk(args->to);
  429.  
  430.     if(!err)
  431.     {
  432.       if(!(err = xadGetHookAccess(ai, XAD_INFILENAME, args->from, dvi ? XAD_OUTDEVICE :
  433.       XAD_OUTFILENAME, dvi ? (ULONG) dvi : (ULONG) args->to, XAD_OVERWRITE, args->overwrite,
  434.       XAD_IGNOREGEOMETRY, args->ignoregeometry, XAD_FORMAT, args->format, XAD_VERIFY,
  435.       TRUE, XAD_PROGRESSHOOK, &prhook, TAG_DONE)))
  436.       {
  437.         err = xadHookAccess(XADAC_COPY, ai->xai_InSize, 0, ai);
  438.         xadFreeHookAccess(ai, err ? TAG_DONE : XAD_WASERROR, err, TAG_DONE);
  439.       }
  440.       xadFreeObjectA(dvi, 0);
  441.     }
  442.     else
  443.       err = XADERR_NOMEMORY;
  444.     xadFreeObjectA(ai,0);
  445.   }
  446.   else
  447.     err = XADERR_NOMEMORY;
  448.  
  449.   return err;
  450. }
  451.  
  452. LONG AskInsertDisk(STRPTR name)
  453. {
  454.   UBYTE r;
  455.   STRPTR b;
  456.           
  457.   for(b = name; *b; ++b)
  458.     *b = toupper(*b);
  459.  
  460.   Printf("\r\033[KInsert disk into %s: and press <ENTER> (any other key to abort): ", name);
  461.   Flush(Output());
  462.   SetMode(Input(), TRUE);
  463.   r = FGetC(Input());
  464.   SetMode(Input(), FALSE);
  465.   if(r != '\r' && r != '\n')
  466.   {
  467.     Printf("\n");
  468.     return XADERR_BREAK;
  469.   }
  470.   return 0;
  471. }
  472.